﻿#region License, Terms and Author(s)
//
// ELMAH - Error Logging Modules and Handlers for ASP.NET
// Copyright (c) 2004-12 Atif Aziz. All rights reserved.
//
//  Author(s):
//
//      Philip Daniels, http://www.philipdaniels.com/
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#endregion

namespace Elmah
{
    #region Imports
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;

    #endregion

    /// <summary>
    /// Represents a structure into which we can place the searchable fields so that we can
    /// pass a single parameter into a method rather than 20. Trims string fields so callers
    /// don't have to worry about it, converts blank strings to null, and converts date criteria
    /// of the form "> 2012-04-01" to separate DateTime structures.
    /// </summary>
    public class SearchCriteria
    {
        public int PageIndex { get; set; }
        public int PageSize { get; set; }

        /// <summary>
        /// Returns true if at least 1 of the extended search criteria
        /// (i.e. not paging or the application name) is set.
        /// </summary>
        public bool ContainsExtendedSearchCriteria
        {
            get
            {
                return Host != null ||
                    TypeName != null ||
                    Source != null ||
                    Message != null ||
                    User != null ||
                    StatusCode != null ||
                    AllXml != null ||
                    TimeUtcFrom != null ||
                    TimeUtcTo != null;
            }
        }

        public string Host
        {
            get
            {
                return _host;
            }
            set
            {
                _host = TrimInputValue(value);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _host;

        public string TypeName
        {
            get
            {
                return _typeName;
            }
            set
            {
                _typeName = TrimInputValue(value);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _typeName;

        public string Source
        {
            get
            {
                return _source;
            }
            set
            {
                _source = TrimInputValue(value);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _source;

        public string Message
        {
            get
            {
                return _message;
            }
            set
            {
                _message = TrimInputValue(value);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _message;

        public string User
        {
            get
            {
                return _user;
            }
            set
            {
                _user = TrimInputValue(value);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _user;

        public string StatusCode
        {
            get
            {
                return _statusCode;
            }
            set
            {
                _statusCode = TrimInputValue(value);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _statusCode;

        public string AllXml
        {
            get
            {
                return _allXml;
            }
            set
            {
                _allXml = TrimInputValue(value);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _allXml;

        public string When
        {
            get
            {
                return _when;
            }
            set
            {
                _when = TrimInputValue(value);
                SetDateCriteria(_when);
            }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private string _when;


        private void SetDateCriteria(string dateExpression)
        {
            FuzzyDateParser p = new FuzzyDateParser();
            DateTime from, to;

            _timeUtcFrom = null;
            _timeUtcTo = null;

            if (p.TryParse(dateExpression, out from, out to))
            {
                if (from != DateTime.MinValue)
                    _timeUtcFrom = from;
                if (to != DateTime.MinValue)
                    _timeUtcTo = to;
            }
        }

        /// <summary>
        /// The inclusive lower bound of the date range that has been set, or null.
        /// You should use this value in a relation of the form ">=".
        /// </summary>
        public DateTime? TimeUtcFrom
        {
            get { return _timeUtcFrom; }
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        private DateTime? _timeUtcFrom;

        /// <summary>
        /// The exclusive upper bound of the date range that has been set, or null.
        /// You should use this value in a relation of the form "&lt;".
        /// </summary>
        public DateTime? TimeUtcTo
        {
            get { return _timeUtcTo; }
        }
        private DateTime? _timeUtcTo;



        private string TrimInputValue(string v)
        {
            if (v == null || v.Trim() == "")
                return null;
            else
                return v.Trim();
        }
    }
}
